package org.example.oop.io_stream;

import lombok.extern.slf4j.Slf4j;

import java.io.*;

/**
 * org.example.oop.stream
 *
 * @author moLei
 * @description 字符流，只能操作纯文本文件，字符流底层是字节流，实际就是字节流+字符集
 * @since 2025/6/18
 */
@Slf4j
public class CharacterStreamDemo02 {

    private static final String FILE_PATH = "C:\\idea\\study\\test.txt";

    /**
     * 读取文件
     */
    public static void readFile() {
        try (Reader reader = new FileReader(FILE_PATH)) {
            // 默认读取一个字节，如果是中文UTF-8编码格式则会读取3个字节。
            int read;
            int count = 0;
            // 从缓冲区中读取数据到变量read中，若缓冲区没有数据，则从文件中读取数据到缓冲区，长度为8192.字节流没有缓冲区
            while ((read = reader.read()) != -1) {
                count ++;
                if (count == 8190) {
                    // 字符流的缓冲区大小为8192字节，若前面8191个都是英文字节，最后一个为中文字节，那么程序读取最后一个字节时检测到
                    // 该字符为中文就会重新去文件中读取，更新缓冲区。
                    System.out.println("-------");
                }
                // 此时读取出来的数据是int类型，需要转换成char类型
                System.out.print((char) read);
                System.out.println(read);
            }
        } catch (Exception e) {
            log.error("文件操作异常：{}", e.getMessage(), e);
        }
    }

    public static void readFileArray() {
        try (Reader reader = new FileReader(FILE_PATH)) {
            char[] chars = new char[1024];
            int len;
            while ((len = reader.read(chars)) != -1) {
                System.out.println(new String(chars, 0, len));

            }
        } catch (Exception e) {
            log.error("文件操作异常：{}", e.getMessage(), e);
        }
    }

    public static void writeFile() {
        try (Reader reader = new FileReader(FILE_PATH);
             Writer writer = new FileWriter(FILE_PATH, true)) {
            // utf-8中的我，根据字符集的编码方式进行编码，编码后的数据写入文件中
            writer.write(25105);
            //
            writer.write("\r\n");
            writer.write("hello world");
            // 刷新缓冲区，将数据写入文件中，若不刷新的话则会等到程序资源关闭或者缓冲区满才会将数据写入文件中。
            // 若不关闭也不刷新缓冲区，那么后面的数据就会丢失，没有进入文件中
            writer.flush();
            writer.write(new char[]{'a', 'b', 'c', '我'});
        } catch (Exception e) {
            log.error("文件操作异常：{}", e.getMessage(), e);
        }
    }

    public static void writeTest() {
        char[] chars = new char[8191];
        for (int i = 0; i < 8191; i++) {
            chars[i] = 'a';
        }
        try (Writer writer = new FileWriter(FILE_PATH)) {
            writer.write(chars);
            writer.flush();
            writer.write("你好");
        } catch (Exception e) {
            log.error("文件操作异常：{}", e.getMessage(), e);
        }
    }

    /**
     * 相比Reader和Writer多了readLine()方法，可以一次读取一行数据和newLine()方法, 可以跨平台写入换行符
     * 字符缓冲区的缓冲区大小为8192字符
     */
    public static void BufferedReaderDemo() {

        try( BufferedReader reader = new BufferedReader(new FileReader(FILE_PATH));
            BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH, true))) {
            // readLine()方法，读取一行数据,不会读取换行符，写入的时候需要手动换行
            String line;
            while ((line = reader.readLine()) != null) {
                writer.write(line);
                writer.newLine();
            }
        } catch (Exception e) {
            log.error("文件操作异常：{}", e.getMessage(), e);
        }
    }

    public static void main(String[] args) {
        readFile();
        // readFileArray();
        // writeFile();
        // writeTest();
    }
}
